package src.unapec.seguridad.ejemplos.EncriptacionArchivos;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import src.unapec.seguridad.ejemplos.Utils.*;

public class EncriptacionArchivos {

	private Cipher cipherEncrypter;
	private Cipher cipherDecrypter;
	byte[] initVector = null;
	AlgorithmParameterSpec algParamSpec = null;
	
	//"algorithm/mode/padding" or "algorithm" 
	//Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
	//Cipher c = Cipher.getInstance("DES");
	
	//"DES/CFB8/NoPadding"
	//"DES/OFB32/PKCS5Padding"
	
	//http://www.users.zetnet.co.uk/hopwood/crypto/scan/cs.html
	
	public EncriptacionArchivos(){
		
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		
		//for CBC; must be 8 bytes
		initVector = new byte[] { 0x10, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x02 };		
		algParamSpec = new IvParameterSpec(initVector);
		
	}
	
	public void writeFile(String inPath,String outPath,SecretKey key){
		

		try {

			AlgorithmParameterSpec algParamSpec = new IvParameterSpec(initVector);
			cipherEncrypter = Cipher.getInstance("DES/CBC/PKCS5Padding");
			cipherEncrypter.init(Cipher.ENCRYPT_MODE, key, algParamSpec);
			
			FileInputStream fis = new FileInputStream(inPath);
			FileOutputStream fos = new FileOutputStream(outPath);
			
			int dataInputSize = fis.available();
			byte[] inputBytes = new byte[dataInputSize];
			fis.read(inputBytes);

			CipherOutputStream cos = new CipherOutputStream(fos, cipherEncrypter);
			cos.write(inputBytes, 0, inputBytes.length);
			cos.close();
			
			fos.flush();
			fis.close();
			fos.close();
			
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
	}
	
	public String readFile(String inPath, SecretKey key){
		
		byte[] decrypted = null;
		
		try {
			
			cipherDecrypter = Cipher.getInstance("DES/CBC/PKCS5Padding");
			cipherDecrypter.init(Cipher.DECRYPT_MODE, key, algParamSpec);

			FileInputStream fis = new FileInputStream(inPath);

			decrypted = new byte[fis.available()];

			CipherInputStream cis = new CipherInputStream(fis, cipherDecrypter);
			int pos = 0, intValue;

			while ((intValue = cis.read()) != -1) {
				decrypted[pos] = (byte) intValue;
				pos++;
			}

			fis.close();
						
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidAlgorithmParameterException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
		
		return new String(decrypted);

		
	}
	
	public static void main(String[] args) {
		
		EncriptacionArchivos io = new EncriptacionArchivos();
		//io.writeFile("/home/rmatos/Desktop/cipherTest.in", "/home/rmatos/Desktop/cipherTest1.out", new Key().getKeys(1));
		System.out.println(io.readFile("/home/rmatos/Desktop/cipherTest.out", new Key().getKeys(1)));
		
	}

}


